﻿using System;
using System.Collections.Generic;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Net;
using Microsoft.Xna.Framework.Storage;
using Microsoft.Xna.Framework.Media;
using System.Configuration;
using Kaleta.Network;
using Lidgren.Network;
using System.Text;
using SkinnedModel;

namespace StarWarsGame
{
    public class Game : Microsoft.Xna.Framework.Game
    {
        public struct PlayerTagName
        {
            public string TagName;
            public PlayerTagName(string tagName)
            {
                TagName = tagName;
            }
        }

        private struct VertexPointSprite
        {
            private Vector3 position;
            private float pointSize;

            public VertexPointSprite(Vector3 position, float pointSize)
            {
                this.position = position;
                this.pointSize = pointSize;
            }

            public static readonly VertexElement[] VertexElements =
              {
                  new VertexElement(0, 0, VertexElementFormat.Vector3, VertexElementMethod.Default, VertexElementUsage.Position, 0),
                  new VertexElement(0, sizeof(float)*3, VertexElementFormat.Single, VertexElementMethod.Default, VertexElementUsage.PointSize, 0),
              };
            public static int SizeInBytes = sizeof(float) * (3 + 1);
        }



        //laserbolts

        Vector3 target_direction;

        BoundingFrustum view_frustum;

        Vector3[] frustum_corners = new Vector3[8];

        Random random_number = new Random();

        #region random color table
        public class colortable
        {
            public Color[] colors;
            public Random rand;

            public colortable()
            {
                colors = new Color[25];
                rand = new Random();
                colors[0] = Color.Aqua;
                colors[1] = Color.Blue;
                colors[2] = Color.BlueViolet;
                colors[3] = Color.Chartreuse;
                colors[4] = Color.Cyan;
                colors[5] = Color.Crimson;
                colors[6] = Color.DeepPink;
                colors[7] = Color.Fuchsia;
                colors[9] = Color.Goldenrod;
                colors[9] = Color.Green;
                colors[10] = Color.Indigo;
                colors[11] = Color.Red;
                colors[12] = Color.Orange;
                colors[13] = Color.OrangeRed;
                colors[14] = Color.RoyalBlue;
                colors[15] = Color.SpringGreen;
                colors[16] = Color.Yellow;
                colors[17] = Color.Purple;
                colors[18] = Color.Lime;
                colors[19] = Color.MediumBlue;
                colors[20] = Color.MediumVioletRed;


            }
            public Color gimmie()
            {
                return Color.DarkRed;
                // return colors[rand.Next(20)];
            }
        }
        public colortable randcolors = new colortable();
        #endregion


        #region laserbolts
        public class Laserbolt
        {
            Model core;

            public int whichbolt = 0;
            public int i = 0;
            public Random random_number = new Random();

            //            Vector3 work_vector;

            EffectParameter effect_center_to_viewer;
            EffectParameter effect_color;
            EffectParameter effect_matrices_combined;


            EffectTechnique effect_technique;

            Matrix[] shader_matrices_combined = new Matrix[2];




            public void setup_and_fire(Vector3 fstart, Vector3 fDirection, Color fcolor, float speed, bool randoms)//, Matrix startRotation)
            {
                whichbolt++;
                if (whichbolt == 200) whichbolt = 0;  // only allows 20 laserbolts at a time, usually that is plenty.

                bolt[whichbolt].start_position = fstart;

                bolt[whichbolt].bolt_speed = speed;
                bolt[whichbolt].color = fcolor;
                bolt[whichbolt].alive = true;

                if (randoms) // adds some random noise to the direction
                {
                    bolt[whichbolt].direction.X = fDirection.X + (float)(random_number.Next(100) - 50) / 10000f;
                    bolt[whichbolt].direction.Y = fDirection.Y + (float)(random_number.Next(100) - 50) / 10000f;
                    bolt[whichbolt].direction.Z = fDirection.Z + (float)(random_number.Next(100) - 50) / 10000f;

                }
                else
                {
                    bolt[whichbolt].direction = fDirection;
                }


                bolt[whichbolt].world_matrix = Matrix.Identity * Matrix.CreateTranslation(fstart);

                bolt[whichbolt].direction.Normalize();

            }

            public class bolt_manager
            {
                public Matrix world_matrix = Matrix.Identity;
                public Vector3 center_to_viewer,
                               work_vector,
                               direction,
                               trans_save;


                public bool alive = false;

                public float bolt_speed = 0;
                public float distance_travelled;

                public Vector3 start_position;
                public Color color = Color.CornflowerBlue;


                public void update()
                {
                    if (alive)
                    {
                        #region move the world matrix

                        distance_travelled = Vector3.Distance(start_position, world_matrix.Translation);

                        if (distance_travelled < 15) // set a maximum allowable distance here
                        {
                            //  world_matrix.Translation += direction * bolt_speed;

                        }
                        else
                        {
                            alive = false;

                        }


                        // you will need to setup some collision detection somewhere to kill the bolt on impact

                        world_matrix.Translation += direction * bolt_speed;

                        work_vector = world_matrix.Translation;

                        work_vector.Normalize();
                        // - work_vector is camera to laser direction                 

                        // work vector will be used to calculate the orientation of the laserbolt.

                        #endregion


                        #region build the world matrix

                        world_matrix.Forward = direction;

                        world_matrix.Up = Vector3.Normalize(Vector3.Cross(world_matrix.Forward, -work_vector));

                        world_matrix.Right = Vector3.Normalize(Vector3.Cross(world_matrix.Forward, world_matrix.Up));
                        center_to_viewer = world_matrix.Up; // will find right & left in the shader

                        #endregion
                    }
                }


            }//end bolt manager


            public bolt_manager[] bolt = new bolt_manager[200];// this will be an array of bolts



            public void load_and_assign_effects(ContentManager content, string filename, Effect effect)
            {
                core = content.Load<Model>(filename);
                foreach (ModelMesh mesh in core.Meshes)
                    foreach (ModelMeshPart part in mesh.MeshParts)
                        part.Effect = effect;

                effect_color = effect.Parameters["laser_bolt_color"];
                effect_center_to_viewer = effect.Parameters["center_to_viewer"];
                effect_technique = effect.Techniques["laserbolt_technique"];
                effect_matrices_combined = effect.Parameters["world_matrices"];

                for (int i = 0; i < 200; i++)
                {
                    bolt[i] = new bolt_manager();
                    bolt[i].world_matrix = Matrix.Identity;
                }

            }

            public void draw(Matrix view, Matrix projection, GraphicsDevice gd, Effect effect)
            {
                effect.CurrentTechnique = effect_technique;

                for (i = 0; i < 200; i++)
                    if (bolt[i].alive)
                    {
                        Matrix worldMatrix = Matrix.CreateScale(0.0300f, 0.0300f, 0.1000f) * bolt[i].world_matrix;
                        shader_matrices_combined[0] = worldMatrix;
                        shader_matrices_combined[1] = worldMatrix * view * projection;

                        effect_matrices_combined.SetValue(shader_matrices_combined);

                        effect_color.SetValue(bolt[i].color.ToVector4());

                        effect_center_to_viewer.SetValue(bolt[i].center_to_viewer);

                        core.Meshes[0].Draw();
                    }

            }

        }
        public Laserbolt Laserbolts = new Laserbolt();
        Effect your_effect;

        #endregion

        //End laserbolts



        public string PlayerName;

        const int maxGamers = 16;
        const int maxLocalGamers = 4;

        string errorMessage;

        bool multiPlayerGame;

        bool AddHouse = false;

        private int KillCount;
        private int totalEnemies;

        enum CollisionType { None, Building, Boundary, WinObject, Player, Object }

        public enum DirectionMovement { Forward, BackWards, Right, Left }

        int[] buildingHeights = new int[] { 0, 2, 3, 4, 5, 6 };

        public GraphicsDeviceManager graphics;
        public GraphicsDevice device;

        Matrix[] modelTransforms;
        Matrix[] enemyModelTransforms;
        Matrix[] atstModelTransforms;
        Matrix[] stormtrooperModelTransforms;
        Matrix[] rebelModelTransforms;

        public Effect effect;
        public Vector3 lightDirection = new Vector3(3, -2, 5);
        public Matrix viewMatrix;
        public Matrix dudeMatrix;
        public Matrix projectionMatrix;
        public Effect pointSpritesEffect;

        public Texture2D xwingImage;
        public Texture2D rebelImage;

        Texture2D sceneryTexture;
        Texture2D bulletTexture;
        public Texture2D borderTexture;
        Texture2D[] skyboxTextures;
        Model xwingModel;
        Model targetModel;
        Model skyboxModel;
        Model enemyModel;
        Model ATSTModel;
        Model StormtrooperModel;
        bool GameStarted = false;

        bool playerPlaysXWing = false;

        Model dudeModel;
        Model rebelModel;
        AnimationPlayer animationPlayer;
        AnimationClip clip;

        KeyboardState currentKeyboardState;
        GamePadState currentGamePadState;
        protected KeyboardState oldKeyboardState;

        private double statisticNetworkTimeElapsed;
        private long BytesRecieved = 0;
        private long BytesSent = 0;

        Xwing localXwing;
        Rebel localRebel;

        Quaternion cameraRotation = Quaternion.Identity;

        int PlayerHealth;

        // Text
        SpriteBatch spriteBatch;
        SpriteFont spriteFont;


        BasicEffect basicEffect;

        int[,] floorPlan;
        float gameSpeed = 0.5f;

        bool explosionPlays = false;

        VertexBuffer cityVertexBuffer;
        VertexDeclaration texturedVertexDeclaration;
        public VertexDeclaration pointSpriteVertexDeclaration;

        BoundingBox[] buildingBoundingBoxes;
        BoundingBox completeCityBox;

        List<TieFighter> tieFighters = new List<TieFighter>();
        List<ATST> ATSTs = new List<ATST>();
        List<Stormtrooper> Stormtroopers = new List<Stormtrooper>();
        //List<Xwing> Players = new List<Xwing>();
        //List<Rebel> RebelPlayers = new List<Rebel>();
        List<Player> Players = new List<Player>();

        double lastBulletTime = 0;

        public List<Bullet> enemyBulletList = new List<Bullet>();
        public List<Bullet> ATSTBulletList = new List<Bullet>();
        public List<Bullet> stormtrooperBulletList = new List<Bullet>();

        bool PlayerWins = false;
        bool EnemyWins = false;


        public Game()
        {
            graphics = new GraphicsDeviceManager(this);
            Content.RootDirectory = "Content";
            oldKeyboardState = Keyboard.GetState();

        }

        float lastSceneChangedTime;
        /// <summary>
        /// Allows the game to run logic.
        /// </summary>
        protected override void Update(GameTime gameTime)
        {
            if (dudeCreated)
            {
                animationPlayer.Update(gameTime.ElapsedGameTime, true, Matrix.Identity);
            }

            GC.Collect();
            GC.WaitForPendingFinalizers();
            if (this.IsActive)
            {
                HandleInput(gameTime);
                if (startScene.Visible)
                {
                    HandleStartSceneInput(gameTime);
                }
                if (helpScene.Visible && gameTime.TotalGameTime.Seconds > lastSceneChangedTime + 0.5)
                {
                    HandleHelpSceneInput();
                }
                if (playerSetupScene.Visible && gameTime.TotalGameTime.Seconds > lastSceneChangedTime + 0.5)
                {
                    HandlePlayerSetupSceneInput();
                }
            }

            if (DistributionSession.Client == null && DistributionSession.Server == null)
            {
                // If we are not in a network session, update the
                // menu screen that will let us create or join one.
                UpdateMenuScreen();
            }
            else
            {
                // If we are in a network session, update it.
                UpdateNetworkSession(gameTime);
            }

            KeyboardState keyboardState = Keyboard.GetState();
            oldKeyboardState = keyboardState;
            base.Update(gameTime);
        }

        /// <summary>
        /// Menu screen provides options to create or join network sessions.
        /// </summary>
        void UpdateMenuScreen()
        {
        }

        private void CreateServer()
        {
            NetConfiguration serverConfig = new NetConfiguration(this.GetType().Name);
            serverConfig.Port = 666;
            serverConfig.MaxConnections = 4;
            NetServer server = new NetServer(serverConfig);
            server.Start();

            DistributionSession.Initialize(server,
                // new Type[] { typeof(Xwing), typeof(TieFighter), typeof(ATST), typeof(Bullet) });
                new Type[] { typeof(Xwing), typeof(Bullet), typeof(Rebel) });

            DistributionSession.Server.Statistics.Reset();
            //statisticNetworkTimeElapsed = 0;
            //BytesRecieved = 0;

            this.Window.Title = "Server started. Waiting for connections...";
            DistributionSession.ClientDataRecieved += new EventHandler<NetworkDataRecievedEventArgs>(DistributionSession_ClientDataRecieved);
        }

        void DistributionSession_ClientDataRecieved(object sender, NetworkDataRecievedEventArgs e)
        {
            if (e.Sender != null)
            {
                if (e.Sender.Status == NetConnectionStatus.Connected)
                {
                    //if server exist
                    if (DistributionSession.Server != null)
                    {
                        if (localXwing != null)
                        {
                            DistributionSession.ServerDispose(localXwing);
                            DistributionSession.ServerCreate(localXwing);
                        }
                        else if (localRebel != null)
                        {
                            DistributionSession.ServerDispose(localRebel);
                            DistributionSession.ServerCreate(localRebel);
                        }
                    }
                }
            }
        }
        public string IPaddress = "localhost";
        private void CreateClient()
        {
            NetConfiguration clientConfig = new NetConfiguration(this.GetType().Name);
            NetClient client = new NetClient(clientConfig);
            client.Start();
            //System.Net.IPEndPoint ipServer = new System.Net.IPEndPoint(new System.Net.IPAddress(169.254.185.175), 666);

            client.DiscoverKnownServer(IPaddress, 666);
            //client.DiscoverKnownServer("169.254.185.175", 666);

            DistributionSession.Initialize(client,
                //new Type[] { typeof(Xwing), typeof(TieFighter), typeof(ATST), typeof(Bullet) });
                    new Type[] { typeof(Xwing), typeof(Bullet), typeof(Rebel) });
            DistributionSession.ServerDataRecieved += new EventHandler<NetworkDataRecievedEventArgs>(DistributionSession_ServerDataRecieved);
        }

        void DistributionSession_ServerDataRecieved(object sender, NetworkDataRecievedEventArgs e)
        {
            if (e.NetMessageType == NetMessageType.ServerDiscovered)
            {
                DistributionSession.Client.Connect(e.ReadBuffer.ReadIPEndPoint());
                Restart();
                GameStarted = true;
            }
        }

        protected override void UnloadContent()
        {
            if (DistributionSession.Server != null)
                DistributionSession.Server.Shutdown("Server disconnected");

            if (DistributionSession.Client != null)
                DistributionSession.Client.Shutdown("Client disconnected");

        }

        private void UpdateNetwork()
        {
            DistributionSession.ClientUpdate();

            if (DistributionSession.Server != null)
                DistributionSession.ServerUpdate();

            if (DistributionSession.Server == null)
                this.Window.Title = System.Enum.GetName(typeof(NetConnectionStatus), DistributionSession.Client.Status);
        }

        /// <summary>
        /// Updates the state of the network session, moving the tanks
        /// around and synchronizing their state over the network.
        /// </summary>
        void UpdateNetworkSession(GameTime gameTime)
        {

            UpdateGame(gameTime);
            UpdateNetwork();
            if (DistributionSession.Server != null)
            {
                statisticNetworkTimeElapsed += gameTime.ElapsedGameTime.TotalMilliseconds;
                BytesRecieved += DistributionSession.Server.Statistics.BytesSent;
                DistributionSession.Server.Statistics.Reset();

                if (statisticNetworkTimeElapsed > 1000)
                {
                    statisticNetworkTimeElapsed -= 1000;

                    this.Window.Title = "Server bytes sent: " + (BytesRecieved / 1024.0f).ToString() + " KBps";
                    BytesRecieved = 0;

                }
            }
            else if (DistributionSession.Client != null)
            {
                statisticNetworkTimeElapsed += gameTime.ElapsedGameTime.TotalMilliseconds;
                BytesRecieved += DistributionSession.Client.Statistics.BytesReceived;
                BytesSent += DistributionSession.Client.Statistics.BytesSent;

                DistributionSession.Client.Statistics.Reset();

                if (statisticNetworkTimeElapsed > 1000)
                {
                    statisticNetworkTimeElapsed -= 1000;

                    this.Window.Title = "Client bytes recieved: " + (BytesRecieved / 1024.0f).ToString() + " KBps" +
                        "      Client bytes sent: " + (BytesSent / 1024.0f).ToString() + " KBps";

                    BytesRecieved = 0; BytesSent = 0;

                }
            }

        }

        /// <summary>
        /// Handle buttons and keyboard in StartScene
        /// </summary>
        private void HandleStartSceneInput(GameTime gameTime)
        {
            if (CheckEnterA())
            {
                switch (startScene.SelectedMenuIndex)
                {
                    case 0:
                        lastSceneChangedTime = gameTime.TotalGameTime.Seconds;
                        playerSetupScene.IsServer = true;
                        playerSetupScene.Show();
                        startScene.Hide();
                        break;
                    case 1:
                        lastSceneChangedTime = gameTime.TotalGameTime.Seconds;
                        playerSetupScene.IsServer = false;
                        playerSetupScene.Show();
                        startScene.Hide();
                        break;
                    case 2:
                        helpScene.Show();
                        helpScene.helpTextMission.isDoneDrawing = false;
                        helpScene.helpTextMissionHeader.isDoneDrawing = false;
                        helpScene.helpTextControlsHeading.isDoneDrawing = false;
                        helpScene.helpTextPlayerControlsXwingHeading.isDoneDrawing = false;
                        helpScene.helpTextPlayerControlsRebelHeading.isDoneDrawing = false;
                        helpScene.helpTextPlayerControlsXwing.isDoneDrawing = false;
                        helpScene.helpTextPlayerControlsRebel.isDoneDrawing = false;                             
                        startScene.Hide();
                        lastSceneChangedTime = gameTime.TotalGameTime.Seconds;
                        break;
                    case 3:
                        Exit();
                        break;
                }
            }
        }

        /// <summary>
        /// Handle buttons and keyboard in StartScene
        /// </summary>
        private void HandleHelpSceneInput()
        {
            if (CheckEnterA())
            {
                helpScene.Hide();
                startScene.Show();
            }
            if (CheckMenuBackInput())
            {
                helpScene.Hide();
                startScene.Show();
            }
        }

        /// <summary>
        /// Handle buttons and keyboard in StartScene
        /// </summary>
        private void HandlePlayerSetupSceneInput()
        {
            if (CheckEnterA())
            {
                multiPlayerGame = true;
                PlayerName = playerSetupScene.txtBoxNickName.parsedText;
                playerPlaysXWing = !playerSetupScene.playerSelectImage.SecondImageSelected;

                Mouse.SetPosition(device.Viewport.Width / 2, device.Viewport.Height / 2);
                oldMouseState = Mouse.GetState();

                if (playerSetupScene.IsServer)
                {
                    CreateServer();
                    CreateClient();
                    playerSetupScene.Hide();
                }
                else
                {
                    IPaddress = playerSetupScene.txtBoxServerIP.parsedText;
                    CreateClient();
                    playerSetupScene.Hide();
                }
            }
            if (CheckMenuBackInput())
            {
                playerSetupScene.Hide();
                startScene.Show();
            }
        }


        /// <summary>
        /// Check if the Enter Key ou 'A' button was pressed
        /// </summary>
        /// <returns>true, if enter key ou 'A' button was pressed</returns>
        private bool CheckMenuBackInput()
        {
            // Get the Keyboard and GamePad state
            GamePadState gamepadState = GamePad.GetState(PlayerIndex.One);
            KeyboardState keyboardState = Keyboard.GetState();

            bool result = (oldKeyboardState.IsKeyDown(Keys.Escape) &&
                (keyboardState.IsKeyDown(Keys.Escape)));

            return result;
        }


        /// <summary>
        /// Check if the Enter Key ou 'A' button was pressed
        /// </summary>
        /// <returns>true, if enter key ou 'A' button was pressed</returns>
        private bool CheckEnterA()
        {
            // Get the Keyboard and GamePad state
            GamePadState gamepadState = GamePad.GetState(PlayerIndex.One);
            KeyboardState keyboardState = Keyboard.GetState();

            bool result = (oldKeyboardState.IsKeyDown(Keys.Enter) &&
                (keyboardState.IsKeyDown(Keys.Enter)));

            return result;
        }


        protected override void Initialize()
        {
            graphics.PreferredBackBufferWidth = 1200;
            graphics.PreferredBackBufferHeight = 700;
            graphics.IsFullScreen = Convert.ToBoolean(System.Configuration.ConfigurationSettings.AppSettings["Fullscreen"]);
            graphics.ApplyChanges();
            Window.Title = "Star Wars - Episode M";

            LoadFloorPlan();
            lightDirection.Normalize();

            totalEnemies = Convert.ToInt32(System.Configuration.ConfigurationSettings.AppSettings["NrOfTieFighers"]) + Convert.ToInt32(System.Configuration.ConfigurationSettings.AppSettings["NrOfATSTs"]);


            playerPlaysXWing = Convert.ToBoolean(System.Configuration.ConfigurationSettings.AppSettings["PlayerPlaysXWing"]);

            base.Initialize();
        }

        private void LoadTieFighters()
        {
            Random random = new Random();
            Random randomDir = new Random();
            for (int index = 0; index < Convert.ToInt32(System.Configuration.ConfigurationSettings.AppSettings["NrOfTieFighers"]); index++)
            {
                float randomNumberX = (float)random.Next(1, 15);
                float randomNumberY = (float)random.Next(13, 18);
                float randomNumberZ = (float)random.Next(-10, -2);

                Vector3 pos = new Vector3(randomNumberX, randomNumberY, randomNumberZ);
                Quaternion rotation = Quaternion.Identity;
                float moveSpeed = 0.6f;
                float rotationSpeed = 1.6f;


                int randomDirValue = randomDir.Next(4);

                DirectionMovement dirMovement = DirectionMovement.Forward;

                switch (randomDirValue)
                {
                    case 1:
                        dirMovement = DirectionMovement.BackWards;
                        break;
                    case 2:
                        dirMovement = DirectionMovement.Left;
                        break;
                    case 3:
                        dirMovement = DirectionMovement.Right;
                        break;
                    default:
                        break;
                }

                TieFighter tieFighter = new TieFighter(this, pos, rotation, moveSpeed, rotationSpeed, dirMovement, enemyModel);
                tieFighters.Add(tieFighter);

            }
        }

        private void LoadStormtroopers()
        {
            Random random = new Random();
            for (int index = 0; index < Convert.ToInt32(System.Configuration.ConfigurationSettings.AppSettings["NrOfStormtroopers"]); index++)
            {
                int cityWidth = floorPlan.GetLength(0);
                int cityLength = floorPlan.GetLength(1);

                float randomNumberX = (float)random.Next(1, cityWidth);
                float randomNumberZ = (float)random.Next(-cityLength, -2);
                Vector3 position = new Vector3(randomNumberX, 0.13f, randomNumberZ);

                Vector3 pos = position;
                Vector3 viewPosition = new Vector3(7, 7, -4);
                Quaternion rotation = Quaternion.Identity;
                float moveSpeed = 0.2f;
                float rotationSpeed = 1.6f;

                int randomDirValue = random.Next(4);

                DirectionMovement dirMovement = DirectionMovement.Forward;

                switch (randomDirValue)
                {
                    case 1:
                        dirMovement = DirectionMovement.BackWards;
                        break;
                    case 2:
                        dirMovement = DirectionMovement.Left;
                        break;
                    case 3:
                        dirMovement = DirectionMovement.Right;
                        break;
                    default:
                        break;
                }

                Stormtrooper stormtrooper = new Stormtrooper(this, pos, viewPosition, rotation, moveSpeed, rotationSpeed, dirMovement, StormtrooperModel);
                Stormtroopers.Add(stormtrooper);

            }
        }

        // Fonts
        private SpriteFont smallFont, largeFont, scoreFont;
        // Textures
        protected Texture2D startBackgroundTexture, startElementsTexture, helpBackgroundTexture, helpElementsTexture;
        // Game Scenes
        protected StartScene startScene;
        protected HelpScene helpScene;
        protected PlayerSetupScene playerSetupScene;

        protected override void LoadContent()
        {
            PlayerHealth = Convert.ToInt32(System.Configuration.ConfigurationSettings.AppSettings["PlayerHealth"]);

            device = graphics.GraphicsDevice;
            basicEffect = new BasicEffect(device, null);

            // Create SpriteBatch and add services
            spriteBatch = new SpriteBatch(device);
            // Font 2D
            spriteFont = Content.Load<SpriteFont>("BerlinSans");

            effect = Content.Load<Effect>("effects");
            sceneryTexture = Content.Load<Texture2D>("texturemap");
            bulletTexture = Content.Load<Texture2D>("bullet");
            borderTexture = Content.Load<Texture2D>("borderpixel");
            xwingModel = LoadModel("xwing");
            enemyModel = Content.Load<Model>("enemyship");
            ATSTModel = Content.Load<Model>("ATST2");
            rebelModel = Content.Load<Model>("dude2");
            StormtrooperModel = Content.Load<Model>("Stormtrooper");
            enemyModelTransforms = new Matrix[enemyModel.Bones.Count];
            modelTransforms = new Matrix[xwingModel.Bones.Count];
            atstModelTransforms = new Matrix[ATSTModel.Bones.Count];
            stormtrooperModelTransforms = new Matrix[StormtrooperModel.Bones.Count];
            rebelModelTransforms = new Matrix[rebelModel.Bones.Count];
            targetModel = LoadModel("target");
            skyboxModel = LoadModel("skybox", out skyboxTextures);

            xwingImage = Content.Load<Texture2D>("xwingImage");
            rebelImage = Content.Load<Texture2D>("rebelImage");

            your_effect = Content.Load<Effect>("laser_shader"); // load effect before laserbolt

            Laserbolts.load_and_assign_effects(Content, "laserbolt2", your_effect);

            // Load the model.
            dudeModel = Content.Load<Model>("dude");

            // Look up our custom skinning information.
            SkinningData skinningData = dudeModel.Tag as SkinningData;

            if (skinningData == null)
                throw new InvalidOperationException
                    ("This model does not contain a SkinningData tag.");

            // Create an animation player, and start decoding an animation clip.
            animationPlayer = new AnimationPlayer(skinningData);
            clip = skinningData.AnimationClips["Take 001"]; 

            // Create the Start Scene
            smallFont = Content.Load<SpriteFont>("menuSmall");
            largeFont = Content.Load<SpriteFont>("menuLarge");
            startBackgroundTexture = Content.Load<Texture2D>("helpbackground");
            startElementsTexture = Content.Load<Texture2D>("startSceneElements");
            startScene = new StartScene(this, smallFont, largeFont,
                startBackgroundTexture, startElementsTexture, spriteBatch);
            Components.Add(startScene);
            // Start the game in the start Scene :)
            startScene.Show();

            // Create the help Scene

            helpBackgroundTexture = Content.Load<Texture2D>("startbackground");
            helpElementsTexture = Content.Load<Texture2D>("startSceneElements");
            helpScene = new HelpScene(this, smallFont, largeFont,
                helpBackgroundTexture, helpElementsTexture, spriteBatch);
            Components.Add(helpScene);

            // Create the player setup Scene

            playerSetupScene = new PlayerSetupScene(this, smallFont, largeFont,
                startBackgroundTexture, spriteBatch);
            Components.Add(playerSetupScene);

            StormtrooperModel.Root.Transform *= Matrix.CreateRotationZ(MathHelper.ToRadians(90));
            ATSTModel.Root.Transform *= Matrix.CreateRotationZ(MathHelper.ToRadians(-20));
            enemyModel.Root.Transform *= Matrix.CreateRotationZ(MathHelper.ToRadians(90));
            enemyModel.Root.Transform *= Matrix.CreateRotationX(MathHelper.ToRadians(90));
            enemyModel.Root.Transform *= Matrix.CreateRotationY(MathHelper.ToRadians(-90));

            pointSpritesEffect = Content.Load<Effect>("pointsprites");
            pointSpritesEffect.Parameters["SpriteTexture"].SetValue(
                Content.Load<Texture2D>("fire"));

            Song mysong = Content.Load<Song>("music");

            MediaPlayer.Play(mysong);

            SetUpVertices();
            SetUpBoundingBoxes();
            LoadTieFighters();
            LoadStormtroopers();

            pointSpriteVertexDeclaration = new VertexDeclaration(device, VertexPointSprite.VertexElements);
        }

        private Model LoadModel(string assetName)
        {

            Model newModel = Content.Load<Model>(assetName);
            foreach (ModelMesh mesh in newModel.Meshes)
                foreach (ModelMeshPart meshPart in mesh.MeshParts)
                    meshPart.Effect = effect.Clone(device);
            return newModel;
        }

        private Model LoadModel(string assetName, out Texture2D[] textures)
        {

            Model newModel = Content.Load<Model>(assetName);
            textures = new Texture2D[newModel.Meshes.Count];
            int i = 0;
            foreach (ModelMesh mesh in newModel.Meshes)
                foreach (BasicEffect currentEffect in mesh.Effects)
                    textures[i++] = currentEffect.Texture;

            foreach (ModelMesh mesh in newModel.Meshes)
                foreach (ModelMeshPart meshPart in mesh.MeshParts)
                    meshPart.Effect = effect.Clone(device);

            return newModel;
        }

        private void LoadFloorPlan()
        {
            string floorLayout = System.Configuration.ConfigurationSettings.AppSettings["LevelLayout"];
            int floorBlockLength = 0;
            string[] floorBlock = null;
            string[] floors = floorLayout.Split(new char[] { ';' }, StringSplitOptions.RemoveEmptyEntries);
            foreach (string floor in floors)
            {
                floorBlock = floor.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries);
                floorBlockLength = floorBlock.Length;
            }
            floorPlan = new int[floors.Length, floorBlockLength];

            for (int floorIndex = 0; floorIndex < floors.Length; floorIndex++)
            {
                for (int floorBlockIndex = 0; floorBlockIndex < floorBlock.Length; floorBlockIndex++)
                {
                    string currentFloor = floorLayout.Split(new char[] { ';' }, StringSplitOptions.RemoveEmptyEntries)[floorIndex];
                    int currentFloorBlock = Convert.ToInt32(currentFloor.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries)[floorBlockIndex]);
                    floorPlan[floorIndex, floorBlockIndex] = currentFloorBlock;
                }
            }
        }

        private void SetUpBoundingBoxes()
        {
            int cityWidth = floorPlan.GetLength(0);
            int cityLength = floorPlan.GetLength(1);

            ATST atst = null;
            List<BoundingBox> bbList = new List<BoundingBox>();
            for (int x = 0; x < cityWidth; x++)
            {
                for (int z = 0; z < cityLength; z++)
                {
                    int buildingType = floorPlan[x, z];
                    if (buildingType != 0)
                    {
                        int buildingHeight = buildingHeights[buildingType];
                        Vector3[] buildingPoints = new Vector3[2];
                        buildingPoints[0] = new Vector3(x, 0, -z);
                        buildingPoints[1] = new Vector3(x + 1, buildingHeight, -z - 1);

                        if (buildingType == 5)
                        {
                            Vector3 ATSTposition = new Vector3(buildingPoints[1].X - 0.5f, buildingPoints[1].Y + 0.0f, buildingPoints[1].Z + 0.5f);
                            float moveSpeed = 0.01f;
                            atst = new ATST(this, ATSTposition, new Vector3(), Quaternion.Identity, moveSpeed, 0, ATSTModel);
                            if (ATSTs.Count < Convert.ToInt32(System.Configuration.ConfigurationSettings.AppSettings["NrOfATSTs"]))
                            {
                                ATSTs.Add(atst);
                            }
                        }
                        BoundingBox buildingBox = BoundingBox.CreateFromPoints(buildingPoints);
                        bbList.Add(buildingBox);
                    }
                }
            }

            //add house
            if (AddHouse)
            {
                int xpos = 7;
                int zpos = 9;
                int y = 10;
                int ylow = 1;

                int width = 4;
                int length = 4;

                //front wall
                Vector3[] houseBuildingPoints = new Vector3[2];
                houseBuildingPoints[0] = new Vector3(7, 0, -9);
                houseBuildingPoints[1] = new Vector3(7 + 4, 10, -9);


                BoundingBox houseBuildingBox = BoundingBox.CreateFromPoints(houseBuildingPoints);
                bbList.Add(houseBuildingBox);
            }
            //
            buildingBoundingBoxes = bbList.ToArray();

            Vector3[] boundaryPoints = new Vector3[2];
            boundaryPoints[0] = new Vector3(0, 0, 0);
            boundaryPoints[1] = new Vector3(cityWidth, 30, -cityLength);
            completeCityBox = BoundingBox.CreateFromPoints(boundaryPoints);
        }



        private void SetUpCamera()
        {
            viewMatrix = Matrix.CreateLookAt(new Vector3(20, 13, -5), new Vector3(8, 0, -7), new Vector3(0, 1, 0));
            projectionMatrix = Matrix.CreatePerspectiveFieldOfView(MathHelper.PiOver4, device.Viewport.AspectRatio, 0.2f, 500.0f);
        }

        private void SetUpVertices()
        {
            int differentBuildings = buildingHeights.Length - 1;
            float imagesInTexture = 1 + differentBuildings * 2;

            int cityWidth = floorPlan.GetLength(0);
            int cityLength = floorPlan.GetLength(1);


            List<VertexPositionNormalTexture> verticesList = new List<VertexPositionNormalTexture>();
            for (int x = 0; x < cityWidth; x++)
            {
                for (int z = 0; z < cityLength; z++)
                {
                    int currentbuilding = floorPlan[x, z];

                    //floor or ceiling
                    verticesList.Add(new VertexPositionNormalTexture(new Vector3(x, buildingHeights[currentbuilding], -z), new Vector3(0, 1, 0), new Vector2(currentbuilding * 2 / imagesInTexture, 1)));
                    verticesList.Add(new VertexPositionNormalTexture(new Vector3(x, buildingHeights[currentbuilding], -z - 1), new Vector3(0, 1, 0), new Vector2((currentbuilding * 2) / imagesInTexture, 0)));
                    verticesList.Add(new VertexPositionNormalTexture(new Vector3(x + 1, buildingHeights[currentbuilding], -z), new Vector3(0, 1, 0), new Vector2((currentbuilding * 2 + 1) / imagesInTexture, 1)));

                    verticesList.Add(new VertexPositionNormalTexture(new Vector3(x, buildingHeights[currentbuilding], -z - 1), new Vector3(0, 1, 0), new Vector2((currentbuilding * 2) / imagesInTexture, 0)));
                    verticesList.Add(new VertexPositionNormalTexture(new Vector3(x + 1, buildingHeights[currentbuilding], -z - 1), new Vector3(0, 1, 0), new Vector2((currentbuilding * 2 + 1) / imagesInTexture, 0)));
                    verticesList.Add(new VertexPositionNormalTexture(new Vector3(x + 1, buildingHeights[currentbuilding], -z), new Vector3(0, 1, 0), new Vector2((currentbuilding * 2 + 1) / imagesInTexture, 1)));

                    if (currentbuilding != 0)
                    {
                        //front wall
                        verticesList.Add(new VertexPositionNormalTexture(new Vector3(x + 1, 0, -z - 1), new Vector3(0, 0, -1), new Vector2((currentbuilding * 2) / imagesInTexture, 1)));
                        verticesList.Add(new VertexPositionNormalTexture(new Vector3(x, buildingHeights[currentbuilding], -z - 1), new Vector3(0, 0, -1), new Vector2((currentbuilding * 2 - 1) / imagesInTexture, 0)));
                        verticesList.Add(new VertexPositionNormalTexture(new Vector3(x, 0, -z - 1), new Vector3(0, 0, -1), new Vector2((currentbuilding * 2 - 1) / imagesInTexture, 1)));

                        verticesList.Add(new VertexPositionNormalTexture(new Vector3(x, buildingHeights[currentbuilding], -z - 1), new Vector3(0, 0, -1), new Vector2((currentbuilding * 2 - 1) / imagesInTexture, 0)));
                        verticesList.Add(new VertexPositionNormalTexture(new Vector3(x + 1, 0, -z - 1), new Vector3(0, 0, -1), new Vector2((currentbuilding * 2) / imagesInTexture, 1)));
                        verticesList.Add(new VertexPositionNormalTexture(new Vector3(x + 1, buildingHeights[currentbuilding], -z - 1), new Vector3(0, 0, -1), new Vector2((currentbuilding * 2) / imagesInTexture, 0)));

                        //back wall
                        verticesList.Add(new VertexPositionNormalTexture(new Vector3(x + 1, 0, -z), new Vector3(0, 0, 1), new Vector2((currentbuilding * 2) / imagesInTexture, 1)));
                        verticesList.Add(new VertexPositionNormalTexture(new Vector3(x, 0, -z), new Vector3(0, 0, 1), new Vector2((currentbuilding * 2 - 1) / imagesInTexture, 1)));
                        verticesList.Add(new VertexPositionNormalTexture(new Vector3(x, buildingHeights[currentbuilding], -z), new Vector3(0, 0, 1), new Vector2((currentbuilding * 2 - 1) / imagesInTexture, 0)));

                        verticesList.Add(new VertexPositionNormalTexture(new Vector3(x, buildingHeights[currentbuilding], -z), new Vector3(0, 0, 1), new Vector2((currentbuilding * 2 - 1) / imagesInTexture, 0)));
                        verticesList.Add(new VertexPositionNormalTexture(new Vector3(x + 1, buildingHeights[currentbuilding], -z), new Vector3(0, 0, 1), new Vector2((currentbuilding * 2) / imagesInTexture, 0)));
                        verticesList.Add(new VertexPositionNormalTexture(new Vector3(x + 1, 0, -z), new Vector3(0, 0, 1), new Vector2((currentbuilding * 2) / imagesInTexture, 1)));

                        //left wall
                        verticesList.Add(new VertexPositionNormalTexture(new Vector3(x, 0, -z), new Vector3(-1, 0, 0), new Vector2((currentbuilding * 2) / imagesInTexture, 1)));
                        verticesList.Add(new VertexPositionNormalTexture(new Vector3(x, 0, -z - 1), new Vector3(-1, 0, 0), new Vector2((currentbuilding * 2 - 1) / imagesInTexture, 1)));
                        verticesList.Add(new VertexPositionNormalTexture(new Vector3(x, buildingHeights[currentbuilding], -z - 1), new Vector3(-1, 0, 0), new Vector2((currentbuilding * 2 - 1) / imagesInTexture, 0)));

                        verticesList.Add(new VertexPositionNormalTexture(new Vector3(x, buildingHeights[currentbuilding], -z - 1), new Vector3(-1, 0, 0), new Vector2((currentbuilding * 2 - 1) / imagesInTexture, 0)));
                        verticesList.Add(new VertexPositionNormalTexture(new Vector3(x, buildingHeights[currentbuilding], -z), new Vector3(-1, 0, 0), new Vector2((currentbuilding * 2) / imagesInTexture, 0)));
                        verticesList.Add(new VertexPositionNormalTexture(new Vector3(x, 0, -z), new Vector3(-1, 0, 0), new Vector2((currentbuilding * 2) / imagesInTexture, 1)));

                        //right wall
                        verticesList.Add(new VertexPositionNormalTexture(new Vector3(x + 1, 0, -z), new Vector3(1, 0, 0), new Vector2((currentbuilding * 2) / imagesInTexture, 1)));
                        verticesList.Add(new VertexPositionNormalTexture(new Vector3(x + 1, buildingHeights[currentbuilding], -z - 1), new Vector3(1, 0, 0), new Vector2((currentbuilding * 2 - 1) / imagesInTexture, 0)));
                        verticesList.Add(new VertexPositionNormalTexture(new Vector3(x + 1, 0, -z - 1), new Vector3(1, 0, 0), new Vector2((currentbuilding * 2 - 1) / imagesInTexture, 1)));

                        verticesList.Add(new VertexPositionNormalTexture(new Vector3(x + 1, buildingHeights[currentbuilding], -z - 1), new Vector3(1, 0, 0), new Vector2((currentbuilding * 2 - 1) / imagesInTexture, 0)));
                        verticesList.Add(new VertexPositionNormalTexture(new Vector3(x + 1, 0, -z), new Vector3(1, 0, 0), new Vector2((currentbuilding * 2) / imagesInTexture, 1)));
                        verticesList.Add(new VertexPositionNormalTexture(new Vector3(x + 1, buildingHeights[currentbuilding], -z), new Vector3(1, 0, 0), new Vector2((currentbuilding * 2) / imagesInTexture, 0)));
                    }
                }
            }



            if (AddHouse)
            {
                int xpos = 7;
                int zpos = 9;
                int y = 10;
                int ylow = 1;

                int width = 4;
                int length = 4;
                float imagesInTextureValue = 1 + differentBuildings * 2;
                verticesList = createHouse(verticesList, imagesInTextureValue, xpos, zpos, y, ylow, width, length);

            }

            cityVertexBuffer = new VertexBuffer(device, verticesList.Count * VertexPositionNormalTexture.SizeInBytes, BufferUsage.WriteOnly);

            cityVertexBuffer.SetData<VertexPositionNormalTexture>(verticesList.ToArray());
            texturedVertexDeclaration = new VertexDeclaration(device, VertexPositionNormalTexture.VertexElements);
        }

        private List<VertexPositionNormalTexture> createHouse(List<VertexPositionNormalTexture> verticesList,
            float imagesInTexture,
            int xpos, int zpos, int y,
            int ylow, int width, int length)
        {


            //front wall
            verticesList.Add(new VertexPositionNormalTexture(new Vector3(xpos + length, 0, -zpos - width), new Vector3(0, 0, -1), new Vector2((ylow * 2) / imagesInTexture, 1)));
            verticesList.Add(new VertexPositionNormalTexture(new Vector3(xpos, y, -zpos - width), new Vector3(0, 0, -1), new Vector2((ylow * 2 - 1) / imagesInTexture, 0)));
            verticesList.Add(new VertexPositionNormalTexture(new Vector3(xpos, 0, -zpos - width), new Vector3(0, 0, -1), new Vector2((ylow * 2 - 1) / imagesInTexture, 1)));

            verticesList.Add(new VertexPositionNormalTexture(new Vector3(xpos, y, -zpos - width), new Vector3(0, 0, -1), new Vector2((ylow * 2 - 1) / imagesInTexture, 0)));
            verticesList.Add(new VertexPositionNormalTexture(new Vector3(xpos + length, 0, -zpos - width), new Vector3(0, 0, -1), new Vector2((ylow * 2) / imagesInTexture, 1)));
            verticesList.Add(new VertexPositionNormalTexture(new Vector3(xpos + length, y, -zpos - width), new Vector3(0, 0, -1), new Vector2((ylow * 2) / imagesInTexture, 0)));

            //front innerwall
            verticesList.Add(new VertexPositionNormalTexture(new Vector3(xpos + length, 0, -zpos - width), new Vector3(0, 0, 1), new Vector2((ylow * 2) / imagesInTexture, 1)));
            verticesList.Add(new VertexPositionNormalTexture(new Vector3(xpos, 0, -zpos - width), new Vector3(0, 0, 1), new Vector2((ylow * 2 - 1) / imagesInTexture, 1)));
            verticesList.Add(new VertexPositionNormalTexture(new Vector3(xpos, y, -zpos - width), new Vector3(0, 0, 1), new Vector2((ylow * 2 - 1) / imagesInTexture, 0)));

            verticesList.Add(new VertexPositionNormalTexture(new Vector3(xpos, y, -zpos - width), new Vector3(0, 0, 1), new Vector2((ylow * 2 - 1) / imagesInTexture, 0)));
            verticesList.Add(new VertexPositionNormalTexture(new Vector3(xpos + length, y, -zpos - width), new Vector3(0, 0, 1), new Vector2((ylow * 2) / imagesInTexture, 0)));
            verticesList.Add(new VertexPositionNormalTexture(new Vector3(xpos + length, 0, -zpos - width), new Vector3(0, 0, 1), new Vector2((ylow * 2) / imagesInTexture, 1)));





            //back wall
            verticesList.Add(new VertexPositionNormalTexture(new Vector3(xpos + length, 0, -zpos), new Vector3(0, 0, 1), new Vector2((ylow * 2) / imagesInTexture, 1)));
            verticesList.Add(new VertexPositionNormalTexture(new Vector3(xpos, 0, -zpos), new Vector3(0, 0, 1), new Vector2((ylow * 2 - 1) / imagesInTexture, 1)));
            verticesList.Add(new VertexPositionNormalTexture(new Vector3(xpos, y, -zpos), new Vector3(0, 0, 1), new Vector2((ylow * 2 - 1) / imagesInTexture, 0)));

            verticesList.Add(new VertexPositionNormalTexture(new Vector3(xpos, y, -zpos), new Vector3(0, 0, 1), new Vector2((ylow * 2 - 1) / imagesInTexture, 0)));
            verticesList.Add(new VertexPositionNormalTexture(new Vector3(xpos + length, y, -zpos), new Vector3(0, 0, 1), new Vector2((ylow * 2) / imagesInTexture, 0)));
            verticesList.Add(new VertexPositionNormalTexture(new Vector3(xpos + length, 0, -zpos), new Vector3(0, 0, 1), new Vector2((ylow * 2) / imagesInTexture, 1)));

            //back innerwall
            verticesList.Add(new VertexPositionNormalTexture(new Vector3(xpos + length, 0, -zpos), new Vector3(0, 0, -1), new Vector2((ylow * 2) / imagesInTexture, 1)));
            verticesList.Add(new VertexPositionNormalTexture(new Vector3(xpos, y, -zpos), new Vector3(0, 0, -1), new Vector2((ylow * 2 - 1) / imagesInTexture, 0)));
            verticesList.Add(new VertexPositionNormalTexture(new Vector3(xpos, 0, -zpos), new Vector3(0, 0, -1), new Vector2((ylow * 2 - 1) / imagesInTexture, 1)));

            verticesList.Add(new VertexPositionNormalTexture(new Vector3(xpos, y, -zpos), new Vector3(0, 0, -1), new Vector2((ylow * 2 - 1) / imagesInTexture, 0)));
            verticesList.Add(new VertexPositionNormalTexture(new Vector3(xpos + length, 0, -zpos), new Vector3(0, 0, -1), new Vector2((ylow * 2) / imagesInTexture, 1)));
            verticesList.Add(new VertexPositionNormalTexture(new Vector3(xpos + length, y, -zpos), new Vector3(0, 0, -1), new Vector2((ylow * 2) / imagesInTexture, 0)));





            ////right testwall
            verticesList.Add(new VertexPositionNormalTexture(new Vector3(xpos + length, 0, -zpos), new Vector3(1, 0, 0), new Vector2((ylow * 2) / imagesInTexture, 1)));
            verticesList.Add(new VertexPositionNormalTexture(new Vector3(xpos + length, y, -zpos - width), new Vector3(1, 0, 0), new Vector2((ylow * 2 - 1) / imagesInTexture, 0)));
            verticesList.Add(new VertexPositionNormalTexture(new Vector3(xpos + length, 0, -zpos - width), new Vector3(1, 0, 0), new Vector2((ylow * 2 - 1) / imagesInTexture, 1)));

            verticesList.Add(new VertexPositionNormalTexture(new Vector3(xpos + length, y, -zpos - width), new Vector3(1, 0, 0), new Vector2((ylow * 2 - 1) / imagesInTexture, 0)));
            verticesList.Add(new VertexPositionNormalTexture(new Vector3(xpos + length, 0, -zpos), new Vector3(1, 0, 0), new Vector2((ylow * 2) / imagesInTexture, 1)));
            verticesList.Add(new VertexPositionNormalTexture(new Vector3(xpos + length, y, -zpos), new Vector3(1, 0, 0), new Vector2((ylow * 2) / imagesInTexture, 0)));

            //inner right wall
            verticesList.Add(new VertexPositionNormalTexture(new Vector3(xpos + length, 0, -zpos), new Vector3(-1, 0, 0), new Vector2((ylow * 2) / imagesInTexture, 1)));
            verticesList.Add(new VertexPositionNormalTexture(new Vector3(xpos + length, 0, -zpos - width), new Vector3(-1, 0, 0), new Vector2((ylow * 2 - 1) / imagesInTexture, 1)));
            verticesList.Add(new VertexPositionNormalTexture(new Vector3(xpos + length, y, -zpos - width), new Vector3(-1, 0, 0), new Vector2((ylow * 2 - 1) / imagesInTexture, 0)));

            verticesList.Add(new VertexPositionNormalTexture(new Vector3(xpos + length, y, -zpos - width), new Vector3(-1, 0, 0), new Vector2((ylow * 2 - 1) / imagesInTexture, 0)));
            verticesList.Add(new VertexPositionNormalTexture(new Vector3(xpos + length, y, -zpos), new Vector3(-1, 0, 0), new Vector2((ylow * 2) / imagesInTexture, 0)));
            verticesList.Add(new VertexPositionNormalTexture(new Vector3(xpos + length, 0, -zpos), new Vector3(-1, 0, 0), new Vector2((ylow * 2) / imagesInTexture, 1)));

            //left wall
            verticesList.Add(new VertexPositionNormalTexture(new Vector3(xpos, 0, -zpos), new Vector3(-1, 0, 0), new Vector2((ylow * 2) / imagesInTexture, 1)));
            verticesList.Add(new VertexPositionNormalTexture(new Vector3(xpos, 0, -zpos - width), new Vector3(-1, 0, 0), new Vector2((ylow * 2 - 1) / imagesInTexture, 1)));
            verticesList.Add(new VertexPositionNormalTexture(new Vector3(xpos, y, -zpos - width), new Vector3(-1, 0, 0), new Vector2((ylow * 2 - 1) / imagesInTexture, 0)));

            verticesList.Add(new VertexPositionNormalTexture(new Vector3(xpos, y, -zpos - width), new Vector3(-1, 0, 0), new Vector2((ylow * 2 - 1) / imagesInTexture, 0)));
            verticesList.Add(new VertexPositionNormalTexture(new Vector3(xpos, y, -zpos), new Vector3(-1, 0, 0), new Vector2((ylow * 2) / imagesInTexture, 0)));
            verticesList.Add(new VertexPositionNormalTexture(new Vector3(xpos, 0, -zpos), new Vector3(-1, 0, 0), new Vector2((ylow * 2) / imagesInTexture, 1)));

            //inner left wall
            verticesList.Add(new VertexPositionNormalTexture(new Vector3(xpos, 0, -zpos), new Vector3(1, 0, 0), new Vector2((ylow * 2) / imagesInTexture, 1)));
            verticesList.Add(new VertexPositionNormalTexture(new Vector3(xpos, y, -zpos - width), new Vector3(1, 0, 0), new Vector2((ylow * 2 - 1) / imagesInTexture, 0)));
            verticesList.Add(new VertexPositionNormalTexture(new Vector3(xpos, 0, -zpos - width), new Vector3(1, 0, 0), new Vector2((ylow * 2 - 1) / imagesInTexture, 1)));

            verticesList.Add(new VertexPositionNormalTexture(new Vector3(xpos, y, -zpos - width), new Vector3(1, 0, 0), new Vector2((ylow * 2 - 1) / imagesInTexture, 0)));
            verticesList.Add(new VertexPositionNormalTexture(new Vector3(xpos, 0, -zpos), new Vector3(1, 0, 0), new Vector2((ylow * 2) / imagesInTexture, 1)));
            verticesList.Add(new VertexPositionNormalTexture(new Vector3(xpos, y, -zpos), new Vector3(1, 0, 0), new Vector2((ylow * 2) / imagesInTexture, 0)));

            ////floor or ceiling
            verticesList.Add(new VertexPositionNormalTexture(new Vector3(xpos, y, -zpos), new Vector3(0, 1, 0), new Vector2(ylow * 2 / imagesInTexture, 1)));
            verticesList.Add(new VertexPositionNormalTexture(new Vector3(xpos, y, -zpos - width), new Vector3(0, 1, 0), new Vector2((ylow * 2) / imagesInTexture, 0)));
            verticesList.Add(new VertexPositionNormalTexture(new Vector3(xpos + length, y, -zpos), new Vector3(0, 1, 0), new Vector2((ylow * 2 + 1) / imagesInTexture, 1)));

            verticesList.Add(new VertexPositionNormalTexture(new Vector3(xpos, y, -zpos - width), new Vector3(0, 1, 0), new Vector2((ylow * 2) / imagesInTexture, 0)));
            verticesList.Add(new VertexPositionNormalTexture(new Vector3(xpos + length, y, -zpos - width), new Vector3(0, 1, 0), new Vector2((ylow * 2 + 1) / imagesInTexture, 0)));
            verticesList.Add(new VertexPositionNormalTexture(new Vector3(xpos + length, y, -zpos), new Vector3(0, 1, 0), new Vector2((ylow * 2 + 1) / imagesInTexture, 1)));

            return verticesList;
        }


        protected void UpdateGame(GameTime gameTime)
        {
            if (localXwing != null)
            {
                if (PlayerHealth <= 0)
                {
                    EnemyWins = true;
                }
                ReadXwingInputs(gameTime);
                GameLogic logic = new GameLogic();
                float playerMoveSpeed = gameTime.ElapsedGameTime.Milliseconds / 500.0f * logic.GameSpeed * localXwing.MoveSpeed;
                Vector3 addVector = Vector3.Transform(new Vector3(0, 0, -1), localXwing.Rotation);
                Vector3 localXwingNewPosition = localXwing.Position;

                localXwingNewPosition += addVector * playerMoveSpeed;
                localXwing.Position = localXwingNewPosition;

                localXwing.locPosition = localXwing.Position;
                localXwing.locRotation = localXwing.Rotation;
                localXwing.locLastBulletTime = localXwing.LastBulletTime;
                localXwing.locMoveSpeed = localXwing.MoveSpeed;

                UpdateCamera(localXwing.Position, localXwing.Rotation);
            }
            else if (localRebel != null)
            {
                if (PlayerHealth <= 0)
                {
                    EnemyWins = true;
                }

                ReadRebelInputs(gameTime);
                GameLogic logic = new GameLogic();
                Vector3 localRebelNewPosition = new Vector3();
                float playerMoveSpeed = 0.0f;
                Vector3 addVector = new Vector3();
                if (localRebel.ForwardSpeed != 0)
                {
                    playerMoveSpeed = gameTime.ElapsedGameTime.Milliseconds / 500.0f * logic.GameSpeed * localRebel.ForwardSpeed;
                    addVector = Vector3.Transform(new Vector3(0, 0, -1), localRebel.Rotation);
                    localRebelNewPosition = localRebel.Position;
                }
                if (localRebel.StrafeSpeed != 0)
                {
                    playerMoveSpeed = gameTime.ElapsedGameTime.Milliseconds / 500.0f * logic.GameSpeed * localRebel.StrafeSpeed;
                    addVector = Vector3.Transform(new Vector3(-1, 0, 0), localRebel.Rotation);
                    localRebelNewPosition = localRebel.Position;
                }
                if (playerMoveSpeed != 0.0f)
                {
                    localRebelNewPosition += addVector * playerMoveSpeed;
                    localRebel.Position = new Vector3(localRebelNewPosition.X, localRebel.Position.Y, localRebelNewPosition.Z);
                }

                localRebel.locPosition = localRebel.Position;
                localRebel.locRotation = localRebel.Rotation;
                localRebel.locLastBulletTime = localRebel.LastBulletTime;

                UpdateCamera(localRebel.Position, localRebel.Rotation);

            }

            float moveSpeed = gameTime.ElapsedGameTime.Milliseconds / 500.0f * gameSpeed;

            if (!PlayerWins && !EnemyWins)
            {
                Players.Clear();                
                foreach (DistributableObject obj in DistributionSession.DistributableObjects.Values)
                {
                    if (obj is Xwing)
                    {
                        Xwing xwing = obj as Xwing;
                        Players.Add(new Player(xwing.Position, xwing.Rotation, xwing.MoveSpeed));
                    }

                    if (obj is Rebel)
                    {
                        Rebel rebel = obj as Rebel;
                        Players.Add(new Player(rebel.Position, rebel.Rotation, rebel.ForwardSpeed));
                    }

                }

                if (localXwing != null)
                {
                    BoundingSphere xwingSpere = new BoundingSphere(localXwing.Position, 0.04f);

                    if (CheckCollision(xwingSpere) != CollisionType.None)
                    {
                        PlayerHealth = PlayerHealth - 20;

                        GameLogic logic = new GameLogic();
                        float playerMoveSpeed = gameTime.ElapsedGameTime.Milliseconds / 500.0f * logic.GameSpeed * localXwing.MoveSpeed;
                        Vector3 addVector = Vector3.Transform(new Vector3(0, 0, 100), localXwing.Rotation);
                        Vector3 localXwingNewPosition = localXwing.Position;
                        localXwingNewPosition += addVector * playerMoveSpeed;
                        localXwing.Position = localXwingNewPosition;
                        localXwing.locPosition = localXwing.Position;

                        localXwing.Rotation = Quaternion.Conjugate(localXwing.Rotation);
                        localXwing.locRotation = localXwing.Rotation;

                    }
                }

                else if (localRebel != null)
                {
                    BoundingSphere localRebelSpere = new BoundingSphere(new Vector3(localRebel.Position.X, localRebel.Position.Y+0.04f, localRebel.Position.Z), 0.04f);

                    if (CheckCollision(localRebelSpere) != CollisionType.None)
                    {
                        //Walking into a wall does not hurt player
                       // PlayerHealth = PlayerHealth - 20;

                        GameLogic logic = new GameLogic();
                        float playerMoveSpeed = gameTime.ElapsedGameTime.Milliseconds / 500.0f * logic.GameSpeed * localRebel.NormalSpeed;
                        Vector3 addVector = Vector3.Transform(new Vector3(0, 0, 100), localRebel.Rotation);
                        Vector3 localRebelNewPosition = localRebel.Position;
                        localRebelNewPosition += addVector * playerMoveSpeed;
                        localRebel.Position = localRebelNewPosition;
                        localRebel.locPosition = localRebel.Position;

                        localRebel.Rotation = Quaternion.Conjugate(localRebel.Rotation);
                        localRebel.locRotation = localRebel.Rotation;

                    }
                }

                Random random = new Random();
                foreach (TieFighter tieFighter in tieFighters)
                {
                    BoundingSphere enemySpere = new BoundingSphere(tieFighter.Position, 0.04f);
                    if (CheckCollision(enemySpere) != CollisionType.None)
                    {
                        if (!tieFighter.InFov)
                        {
                            float randomNumberX2 = (float)random.Next(1, 15);
                            float randomNumberY2 = (float)random.Next(1, 15);
                            float randomNumberZ2 = (float)random.Next(-10, -2);
                            Vector3 newStartEnemyPosition = new Vector3(randomNumberX2, randomNumberY2, randomNumberZ2);

                            tieFighter.Position = newStartEnemyPosition;
                        }
                    }
                }

                
                foreach (ATST atst in ATSTs)
                {
                    atst.UpdatePosition(gameTime, Players);
                    atst.Fire(gameTime);

                }

                foreach (TieFighter tieFighter in tieFighters)
                {
                    tieFighter.UpdatePosition(gameTime, Players);
                    tieFighter.Fire(gameTime);
                }

                foreach (Stormtrooper stormtrooper in Stormtroopers)
                {
                    stormtrooper.UpdatePosition(gameTime, Players);
                    stormtrooper.Fire(gameTime);
                }
            }

            UpdateBulletPositions(moveSpeed);
            base.Update(gameTime);
        }
        Vector3 camup;
        private void UpdateCamera(Vector3 lookAtPos, Quaternion rotation)
        {
            cameraRotation = Quaternion.Lerp(cameraRotation, rotation, 0.1f);
            Vector3 campos = new Vector3(0, 0.1f, 0.6f);

             campos = Vector3.Transform(campos, Matrix.CreateFromQuaternion(cameraRotation));
            campos += lookAtPos;

            camup = new Vector3(0, 1, 0);
            camup = Vector3.Transform(camup, Matrix.CreateFromQuaternion(cameraRotation));

            viewMatrix = Matrix.CreateLookAt(campos, lookAtPos, camup);
        
            projectionMatrix = Matrix.CreatePerspectiveFieldOfView(MathHelper.PiOver4, device.Viewport.AspectRatio, 0.2f, 500.0f);


            if (localRebel != null)
            {
                cameraRotation = rotation;// Matrix.Identity;
                campos = campos + new Vector3(0, 0.5f, 0);
                camup = new Vector3(0, 1, 0);
                viewMatrix = Matrix.CreateLookAt(campos, MoveForward(lookAtPos, rotation, 100.0f), camup);

                camup = Vector3.Transform(camup, Matrix.CreateFromQuaternion(cameraRotation));
                //dudeMatrix = Matrix.CreateLookAt(campos + new Vector3(-9.5f, 3, 10), MoveForward(lookAtPos, rotation, 100.0f), camup);
                // dudeMatrix = Matrix.CreateLookAt(campos, lookAtPos, new Vector3(0, 1, 0));
                float tempcameraDistance = 0.21f;
                dudeMatrix = Matrix.CreateScale(0.0022f, 0.0022f, 0.0022f) * Matrix.CreateTranslation(0, 0, 0) *
                    ////   Matrix.CreateFromQuaternion(currentRebel.Rotation);// *
                    //  Matrix.CreateRotationY(MathHelper.ToRadians(rebelCameraRotation)) *
                  Matrix.CreateRotationX(MathHelper.ToRadians(rebelCameraArc)) *
                  Matrix.CreateLookAt(new Vector3(0, 0.25f, tempcameraDistance), Vector3.Forward, Vector3.Up);

            }
        
           

          //  UpdateCameraFirstPerson(lookAtPos, rotation);


        }

        void UpdateCameraFirstPerson(Vector3 lookAtPos, Quaternion rotation)
        {
            Matrix rotationMatrix = Matrix.CreateFromQuaternion(rotation);

            // Transform the head offset so the camera is positioned properly relative to the avatar.
            Vector3 headOffset = Vector3.Transform(avatarHeadOffset, rotationMatrix);

            // Calculate the camera's current position.
            Vector3 cameraPosition = lookAtPos + headOffset;

            // Create a vector pointing the direction the camera is facing.
            Vector3 transformedReference = Vector3.Transform(cameraReference, rotationMatrix);

            // Calculate the position the camera is looking at.
            Vector3 cameraLookat = transformedReference + cameraPosition;

            // Set up the view matrix and projection matrix.
            viewMatrix = Matrix.CreateLookAt(cameraPosition, cameraLookat, new Vector3(0.0f, 1.0f, 0.0f));

            Viewport viewport = graphics.GraphicsDevice.Viewport;
            float aspectRatio = (float)viewport.Width / (float)viewport.Height;

            projectionMatrix = Matrix.CreatePerspectiveFieldOfView(MathHelper.PiOver4, aspectRatio, 0.2f, 500.0f);

        }
        Vector3 avatarHeadOffset = new Vector3(0, 0.3f, 0);
        // Set the direction the camera points without rotation.
        Vector3 cameraReference = new Vector3(0, 0, -1);

        /// <summary>
        /// Updates the camera when it's in the 3rd person state.
        /// </summary>
        void UpdateCameraThirdPerson(Vector3 lookAtPos, Quaternion rotation)
        {
            Matrix rotationMatrix = Matrix.CreateFromQuaternion(rotation);

            // Create a vector pointing the direction the camera is facing.
            Vector3 transformedReference = Vector3.Transform(lookAtPos, rotationMatrix);

            // Calculate the position the camera is looking from.
            Vector3 cameraPosition = transformedReference + lookAtPos;

            // Set up the view matrix and projection matrix.
            viewMatrix = Matrix.CreateLookAt(cameraPosition, lookAtPos, new Vector3(0.0f, 1.0f, 0.0f));

            Viewport viewport = graphics.GraphicsDevice.Viewport;
            float aspectRatio = (float)viewport.Width / (float)viewport.Height;

            projectionMatrix = Matrix.CreatePerspectiveFieldOfView(MathHelper.PiOver4, aspectRatio, 0.2f, 500.0f);
        }

  
        private void Restart()
        {
            KillCount = 0;
            tieFighters.Clear();
            ATSTs.Clear();
            Stormtroopers.Clear();
            LoadStormtroopers();
            LoadTieFighters();
            SetUpBoundingBoxes();

            explosionPlays = false;
            enemyBulletList.Clear();
            ATSTBulletList.Clear();
            stormtrooperBulletList.Clear();
            PlayerWins = false;
            EnemyWins = false;

            //randomize ship positions
            Random random = new Random();
            float randomNumberX1 = (float)random.Next(1, 15);
            float randomNumberY1 = (float)random.Next(8, 10);
            float randomNumberZ1 = (float)random.Next(-10, -2);

            Random randomXwing = new Random();
            float randomNumberXwingX1 = (float)randomXwing.Next(1, 15);
            float randomNumberXwingY1 = (float)randomXwing.Next(8, 12);
            float randomNumberXwingZ1 = (float)randomXwing.Next(-10, -2);

            Vector3 startXwingPosition = new Vector3(randomNumberXwingX1, randomNumberXwingY1, randomNumberXwingZ1);

            //xwingPosition = startXwingPosition;          
            PlayerHealth = Convert.ToInt32(System.Configuration.ConfigurationSettings.AppSettings["PlayerHealth"]);

            if (localXwing == null && playerPlaysXWing)
            {
                localXwing = new Xwing();

                // int playerGamerIndex = 0;
                //foreach (DistributableObject xwingObj in DistributionSession.DistributableObjects.Values)
                // {
                //     if (xwingObj is Xwing)
                //     {
                //         playerGamerIndex++;
                //     }
                // }
                //Guid playerID = Guid.NewGuid();
                Random randomID = new Random();
                localXwing.PlayerID = randomID.Next(0, Int32.MaxValue);

                string playerName = playerSetupScene.txtBoxNickName.parsedText;
                localXwing.PlayerName = playerName;

                localXwing.Position = startXwingPosition;
                localXwing.Rotation = Quaternion.Identity;

                localXwing.MoveSpeed = localXwing.NormalSpeed;

                //if server exist
                if (DistributionSession.Server != null)
                {
                    DistributionSession.ServerCreate(localXwing);
                }
                else
                {
                    DistributionSession.DistributeObject(localXwing);
                }

            }
            else if(localRebel == null && !playerPlaysXWing)
            {
                localRebel = new Rebel();
                Random randomID = new Random();
                localRebel.PlayerID = randomID.Next(0, Int32.MaxValue);

                string playerName = playerSetupScene.txtBoxNickName.parsedText;
                localRebel.PlayerName = playerName;

                localRebel.Position = new Vector3(startXwingPosition.X, 0.0001f, startXwingPosition.Z);
                localRebel.Rotation = Quaternion.Identity;              

                //if server exist
                if (DistributionSession.Server != null)
                {
                    DistributionSession.ServerCreate(localRebel);
                }
                else
                {
                    DistributionSession.DistributeObject(localRebel);
                }
            
                animationPlayer.StartClip(clip);
                dudeCreated = true;
            }
        }
        bool dudeCreated = false;

        private CollisionType CheckCollision(BoundingSphere sphere)
        {
            for (int i = 0; i < buildingBoundingBoxes.Length; i++)
                if (buildingBoundingBoxes[i].Contains(sphere) != ContainmentType.Disjoint)
                    return CollisionType.Building;

            if (completeCityBox.Contains(sphere) != ContainmentType.Contains)
                return CollisionType.Boundary;

            return CollisionType.None;
        }

        private CollisionType CheckIfHit(BoundingSphere sphere, bool remove, Xwing currentXwing)
        {
            BoundingSphere playerSpere = new BoundingSphere(currentXwing.Position, 0.04f);

            if (!remove)
            {
                if (playerSpere.Contains(sphere) != ContainmentType.Disjoint)
                    return CollisionType.Player;
            }


            foreach (ATST atst in ATSTs)
            {
                BoundingSphere ATSTSpere = new BoundingSphere(new Vector3(atst.Position.X, atst.Position.Y - 0.3f, atst.Position.Z), 0.60f);
                BoundingSphere ATSTSpere2 = new BoundingSphere(new Vector3(atst.Position.X, atst.Position.Y + 0.3f, atst.Position.Z), 0.60f);
                if (ATSTSpere.Contains(sphere) != ContainmentType.Disjoint || ATSTSpere2.Contains(sphere) != ContainmentType.Disjoint)
                {
                    if (remove)
                    {
                        ATSTs.Remove(atst);
                    }
                    return CollisionType.WinObject;
                }
            }

            foreach (TieFighter tieFighter in tieFighters)
            {
                BoundingSphere tieFighterSpere = new BoundingSphere(tieFighter.Position, 0.40f);
                if (tieFighterSpere.Contains(sphere) != ContainmentType.Disjoint)
                {
                    if (remove)
                    {
                        tieFighters.Remove(tieFighter);
                    }
                    return CollisionType.WinObject;
                }
            }

            foreach (Stormtrooper stormtrooper in Stormtroopers)
            {
                BoundingSphere stormtrooperSpere = new BoundingSphere(stormtrooper.Position, 0.40f);
                if (stormtrooperSpere.Contains(sphere) != ContainmentType.Disjoint)
                {
                    if (remove)
                    {
                        Stormtroopers.Remove(stormtrooper);
                    }
                    return CollisionType.Object;
                }
            }

            return CollisionType.None;
        }

        private Vector3 MoveForward(Vector3 position, Quaternion rotationQuat, float speed)
        {
            Vector3 addVector = Vector3.Transform(new Vector3(0, 0, -1), rotationQuat);
            position += addVector * speed;
            return position;
        }

        private void MoveBackWards(ref Vector3 position, Quaternion rotationQuat, float speed)
        {
            Vector3 addVector = Vector3.Transform(new Vector3(0, 0, 1), rotationQuat);
            position += addVector * speed;
        }


        private void UpdateBulletPositions(float moveSpeed)
        {

            foreach (DistributableObject playerObj in DistributionSession.DistributableObjects.Values)
            {
                if (playerObj is Xwing)
                {

                    Xwing currentXwing = playerObj as Xwing;

                    foreach (DistributableObject obj in DistributionSession.DistributableObjects.Values)
                    {
                        if (obj is Bullet)
                        {
                            Bullet currentBullet = obj as Bullet;
                            Vector3 newPostion = MoveForward(currentBullet.bulletPosition, currentBullet.bulletRotation, moveSpeed * 5.0f);
                            currentBullet.bulletPosition = newPostion;
                            currentBullet.locPosition = currentBullet.bulletPosition;

                            BoundingSphere bulletSphere = new BoundingSphere(currentBullet.bulletPosition, 0.05f);
                            CollisionType colType = CheckCollision(bulletSphere);
                            if (colType != CollisionType.None)
                            {
                                if (DistributionSession.Server != null)
                                {
                                    DistributionSession.ServerDispose(currentBullet);
                                }
                            }

                            CollisionType bulletHitType = CheckIfHit(bulletSphere, true, currentXwing);
                            if (bulletHitType == CollisionType.WinObject)
                            {
                                foreach (DistributableObject currObj in DistributionSession.DistributableObjects.Values)
                                {
                                    if (currObj is Xwing)
                                    {
                                        Xwing playerXwing = currObj as Xwing;
                                        if (playerXwing.PlayerID == currentBullet.bulletOwner)
                                        {
                                            playerXwing.KillCount++;
                                            playerXwing.locKillCount = playerXwing.KillCount;
                                            break;
                                        }

                                    }
                                }

                                KillCount++;
                                if (KillCount == totalEnemies)
                                {
                                    PlayerWins = true;
                                }
                            }
                        }
                    }


                    for (int i = 0; i < enemyBulletList.Count; i++)
                    {
                        Bullet currentBullet = enemyBulletList[i];
                        Vector3 newPosition = MoveForward(currentBullet.bulletPosition, currentBullet.bulletRotation, moveSpeed * 7.0f);
                        currentBullet.bulletPosition = newPosition;
                        enemyBulletList[i] = currentBullet;

                        BoundingSphere bulletSphere = new BoundingSphere(currentBullet.bulletPosition, 0.05f);
                        CollisionType colType = CheckCollision(bulletSphere);
                        if (colType != CollisionType.None && colType != CollisionType.Boundary)
                        {
                            enemyBulletList.RemoveAt(i);
                            i--;
                        }

                        CollisionType bulletHitType = CheckIfHit(bulletSphere, false, currentXwing);
                        if (bulletHitType == CollisionType.Player)
                        {
                            PlayerHealth = PlayerHealth - 10;
                        }
                    }

                    for (int i = 0; i < stormtrooperBulletList.Count; i++)
                    {
                        Bullet currentBullet = stormtrooperBulletList[i];
                        Vector3 newPosition = MoveForward(currentBullet.bulletPosition, currentBullet.bulletRotation, moveSpeed * 7.0f);
                        currentBullet.bulletPosition = newPosition;
                        stormtrooperBulletList[i] = currentBullet;

                        BoundingSphere bulletSphere = new BoundingSphere(currentBullet.bulletPosition, 0.05f);
                        CollisionType colType = CheckCollision(bulletSphere);
                        if (colType != CollisionType.None && colType != CollisionType.Boundary)
                        {
                            stormtrooperBulletList.RemoveAt(i);
                            i--;
                        }

                        CollisionType bulletHitType = CheckIfHit(bulletSphere, false, currentXwing);
                        if (bulletHitType == CollisionType.Player)
                        {
                            PlayerHealth = PlayerHealth - 1;
                        }
                    }

                    for (int i = 0; i < ATSTBulletList.Count; i++)
                    {
                        Bullet currentBullet = ATSTBulletList[i];
                        Vector3 newPosition = MoveForward(currentBullet.bulletPosition, currentBullet.bulletRotation, moveSpeed * 3.0f);
                        currentBullet.bulletPosition = newPosition;
                        ATSTBulletList[i] = currentBullet;

                        BoundingSphere bulletSphere = new BoundingSphere(currentBullet.bulletPosition, 0.05f);
                        CollisionType colType = CheckCollision(bulletSphere);
                        if (colType != CollisionType.None && colType != CollisionType.Boundary)
                        {
                            ATSTBulletList.RemoveAt(i);
                            i--;
                        }

                        CollisionType bulletHitType = CheckIfHit(bulletSphere, false, currentXwing);
                        if (bulletHitType == CollisionType.Player)
                        {
                            PlayerHealth = PlayerHealth - 10;
                        }
                    }

                }

                if (playerObj is Rebel)
                {

                    Rebel currentRebel = playerObj as Rebel;

                    foreach (DistributableObject obj in DistributionSession.DistributableObjects.Values)
                    {
                        if (obj is Bullet)
                        {
                            Bullet currentBullet = obj as Bullet;
                            Vector3 newPostion = MoveForward(currentBullet.bulletPosition, currentBullet.bulletRotation, moveSpeed * 5.0f);
                            currentBullet.bulletPosition = newPostion;
                            currentBullet.locPosition = currentBullet.bulletPosition;

                            BoundingSphere bulletSphere = new BoundingSphere(currentBullet.bulletPosition, 0.05f);
                            CollisionType colType = CheckCollision(bulletSphere);
                            if (colType != CollisionType.None)
                            {
                                if (DistributionSession.Server != null)
                                {
                                    DistributionSession.ServerDispose(currentBullet);
                                }
                            }

                            //CollisionType bulletHitType = CheckIfHit(bulletSphere, true, currentRebel);
                            //if (bulletHitType == CollisionType.WinObject)
                            //{
                            //    foreach (DistributableObject currObj in DistributionSession.DistributableObjects.Values)
                            //    {
                            //        if (currObj is Xwing)
                            //        {
                            //            Xwing playerXwing = currObj as Xwing;
                            //            if (playerXwing.PlayerID == currentBullet.bulletOwner)
                            //            {
                            //                playerXwing.KillCount++;
                            //                playerXwing.locKillCount = playerXwing.KillCount;
                            //                break;
                            //            }

                            //        }
                            //    }

                            //    KillCount++;
                            //    if (KillCount == totalEnemies)
                            //    {
                            //        PlayerWins = true;
                            //    }
                            //}
                        }
                    }
                }
            }
        }

        float rebelCameraArc = 0;
        float rebelCameraRotation = 0;
        float height = 0;

        protected void DrawGame()
        {
            spriteBatch.Begin(SpriteBlendMode.AlphaBlend, SpriteSortMode.Deferred, SaveStateMode.SaveState);
            //playersJoined
            spriteBatch.DrawString(spriteFont,"Players joined: ", new Vector2(graphics.PreferredBackBufferWidth - (graphics.PreferredBackBufferWidth / 4), 45), Color.LightCoral);

            DrawClass drawClass = new DrawClass();
            drawClass.Game = this;
            if (localXwing != null || localRebel != null)
            {
                if (localXwing != null)
                {
                    drawClass.DrawSkybox(skyboxModel, localXwing.Position, skyboxTextures);
                }
                else
                {
                    drawClass.DrawSkybox(skyboxModel, localRebel.Position, skyboxTextures);
                }
            }
            drawClass.DrawCity(sceneryTexture, texturedVertexDeclaration, cityVertexBuffer);
            int NrOfPlayers = 0;
            //draw xwings                     
            foreach (DistributableObject obj in DistributionSession.DistributableObjects.Values)
            {
                if (obj is Xwing)
                {
                    Xwing xwing = obj as Xwing;
                    drawClass.DrawXwing(xwingModel, xwing.Rotation, xwing.Position, modelTransforms);
                    spriteBatch.DrawString(spriteFont, xwing.PlayerName + "     : " + xwing.KillCount, new Vector2(graphics.PreferredBackBufferWidth - (graphics.PreferredBackBufferWidth / 4), 65 + 20 * NrOfPlayers), Color.LightCoral);
                    NrOfPlayers++;
                }
                if (obj is Bullet)
                {
                    Bullet bullet = obj as Bullet;
                    //  drawClass.DrawBullet(bullet);
                }

                if (obj is Rebel)
                {
                    Rebel currentRebel = obj as Rebel;
                    spriteBatch.DrawString(spriteFont, currentRebel.PlayerName + "     : " + currentRebel.KillCount, new Vector2(graphics.PreferredBackBufferWidth - (graphics.PreferredBackBufferWidth / 4), 65 + 20 * NrOfPlayers), Color.LightCoral);
                    NrOfPlayers++;

                    if (localRebel != null && localXwing == null)
                    {
                        // Render the skinned mesh.
                        Matrix[] bones = animationPlayer.GetSkinTransforms();



                        height = 1.5f;
                        // Matrix worldMatrix = Matrix.CreateScale(0.0005f, 0.0005f, 0.0005f) * Matrix.CreateRotationY(MathHelper.Pi) * Matrix.CreateFromQuaternion(xwingRotation) * Matrix.CreateTranslation(xwingPosition);
                        //if (currentRebel.Rotation.Y != 0)
                        //{
                        //    tempcameraDistance = 0.5f;
                        //    height = 0.5f;
                        //}
                        // Matrix dudeWorldMatrix = Matrix.CreateScale(0.0022f, 0.0022f, 0.0022f) *Matrix.CreateTranslation(0,0,0)*
                        ////   Matrix.CreateFromQuaternion(currentRebel.Rotation);// *
                        //  Matrix.CreateRotationY(MathHelper.ToRadians(rebelCameraRotation)) *
                        //  Matrix.CreateRotationX(MathHelper.ToRadians(rebelCameraArc)) *
                        //  Matrix.CreateLookAt(new Vector3(0, 0, tempcameraDistance),new Vector3(0,0,0), Vector3.Up);

                        //Matrix dudeWorldMatrix = Matrix.CreateScale(0.0522f, 0.0522f, 0.0522f) * dudeMatrix;// *Matrix.CreateLookAt(new Vector3(0, 0, tempcameraDistance), new Vector3(0, 0, 0), Vector3.Up);
                        foreach (ModelMesh mesh in dudeModel.Meshes)
                        {
                            foreach (Effect effect in mesh.Effects)
                            {
                                effect.Parameters["Bones"].SetValue(bones);

                                //if (localRebel == null && localXwing != null)
                                //{
                                //    animationPlayer.StartClip(clip);
                                //    dudeCreated = true;
                                //    Vector3 distVector = localXwing.Position-currentRebel.Position;
                                //    if (localXwing.Position.X < currentRebel.Position.X)
                                //    {
                                //        distVector.X = -distVector.X;
                                //    }

                                //    if (localXwing.Position.Y < currentRebel.Position.Y)
                                //    {
                                //        distVector.Y = -distVector.Y;
                                //    }

                                //    if (localXwing.Position.Z < currentRebel.Position.Z)
                                //    {
                                //        distVector.Z = -distVector.Z;
                                //    }


                                //    Matrix dudeMatrix2 = Matrix.CreateScale(0.0022f, 0.0022f, 0.0022f) * Matrix.CreateTranslation(0,0,0) *
                                //        ////   Matrix.CreateFromQuaternion(currentRebel.Rotation);// *
                                //        //  Matrix.CreateRotationY(MathHelper.ToRadians(rebelCameraRotation)) *
                                //        // Matrix.CreateRotationX(MathHelper.ToRadians(rebelCameraArc)) *

                                //   Matrix.CreateLookAt(new Vector3(distVector.X, distVector.Y, distVector.Z), MoveForward(localXwing.Position, localXwing.Rotation, 100.0f), camup);

                                //    effect.Parameters["View"].SetValue(dudeMatrix2);
                                //}
                                //else
                                //{
                                effect.Parameters["View"].SetValue(dudeMatrix);
                                //}

                                effect.Parameters["Projection"].SetValue(projectionMatrix);
                            }

                            mesh.Draw();
                        }
                    }
                    else
                    {
                        //this is a player from the network
                        drawClass.DrawRebel(rebelModel, rebelModelTransforms, currentRebel.Rotation, currentRebel.Position);
                    }
                }


            }
            //  drawClass.DrawATSTBullets(ATSTBulletList);
            drawClass.DrawEnemyBullets(enemyBulletList);

            foreach (ATST atst in ATSTs)
            {
                atst.Draw(atstModelTransforms);
            }

            foreach (TieFighter tieFighter in tieFighters)
            {
                tieFighter.Draw(enemyModelTransforms);
            }

            foreach (Stormtrooper stormtrooper in Stormtroopers)
            {
                stormtrooper.Draw(stormtrooperModelTransforms);
            }

            spriteBatch.DrawString(spriteFont, "Number of players: " + NrOfPlayers, new Vector2(10, 45), Color.Blue);

            //PlayerHealth   
            spriteBatch.DrawString(spriteFont, "Player Health: " + PlayerHealth + " %", new Vector2(10, 85), Color.GreenYellow);

            //PlayerHealth              
            spriteBatch.DrawString(spriteFont, "Enemies killed: " + KillCount + " / " + totalEnemies, new Vector2(10, 105), Color.Yellow);

            //for (int playerIndex = 0; playerIndex < NrOfPlayers; playerIndex++)
            //{
            //    spriteBatch.DrawString(spriteFont, playerNames[playerIndex] + " Kills: "+pl, new Vector2(graphics.PreferredBackBufferWidth - (graphics.PreferredBackBufferWidth / 4), 65 + 20 * playerIndex), Color.LightCoral);
            //}

            if (PlayerWins)
            {
                spriteBatch.DrawString(spriteFont, "You win! Press F1/F2 to restart or Esc to exit.", new Vector2(300, 275), Color.Green);
                if (!explosionPlays)
                {
                    SoundEffect soundEffect = Content.Load<SoundEffect>("explosion");
                    soundEffect.Play();
                    explosionPlays = true;
                }
            }
            if (EnemyWins)
            {
                spriteBatch.DrawString(spriteFont, "You lose! Press F1/F2 to restart or Esc to exit.", new Vector2(300, 275), Color.Red);
                if (!explosionPlays)
                {
                    SoundEffect soundEffect = Content.Load<SoundEffect>("explosion");
                    soundEffect.Play();
                    explosionPlays = true;
                }
            }

            spriteBatch.End();

        }

        #region Handle Input


        /// <summary>
        /// Handles input.
        /// </summary>
        private void HandleInput(GameTime gameTime)
        {
            currentKeyboardState = Keyboard.GetState();
            currentGamePadState = GamePad.GetState(PlayerIndex.One);

            // Check for exit.
            if (IsActive && IsPressed(Keys.Escape, Buttons.Back) && multiPlayerGame)
            {
                if (DistributionSession.Client != null)
                {
                    if (localXwing != null)
                    {
                        DistributionSession.ClientDispose(localXwing);
                    }
                    else if (localRebel != null)
                    {
                        DistributionSession.ClientDispose(localRebel);
                    }
                }
                Exit();
            }
            if (IsActive && IsPressed(Keys.F2, Buttons.Start) && multiPlayerGame)
            {
                timeSinceLastRestart = gameTime.TotalGameTime.Seconds;
                Restart();
            }
            if (IsActive && IsPressed(Keys.F1, Buttons.DPadDown) && multiPlayerGame)
            {
                if (localXwing != null && gameTime.TotalGameTime.Seconds > timeSinceLastRestart + 0.5)
                {
                    if (DistributionSession.Server != null)
                    {
                        DistributionSession.ServerDispose(localXwing);
                        localXwing = null;
                    }
                    else if (DistributionSession.Client != null)
                    {
                        DistributionSession.ClientDispose(localXwing);
                        localXwing = null;
                    }
                }
                else if (localRebel != null && gameTime.TotalGameTime.Seconds > timeSinceLastRestart + 0.5)
                {
                    if (DistributionSession.Server != null)
                    {
                        DistributionSession.ServerDispose(localRebel);
                        localRebel = null;
                    }
                    else if (DistributionSession.Client != null)
                    {
                        DistributionSession.ClientDispose(localRebel);
                        localRebel = null;
                    }
                }
            }

        }
        double timeSinceLastRestart = 0;

        /// <summary>
        /// Checks if the specified button is pressed on either keyboard or gamepad.
        /// </summary>
        bool IsPressed(Keys key, Buttons button)
        {
            return (oldKeyboardState.IsKeyDown(key) && currentKeyboardState.IsKeyDown(key));
        }


        void ReadXwingInputs(GameTime gameTime)
        {
            // Read the gamepad.            
            KeyboardState keys = Keyboard.GetState();

            float leftRightRot = 0;

            float turningSpeed = (float)gameTime.ElapsedGameTime.TotalMilliseconds / 1000.0f;
            turningSpeed *= 1.6f * gameSpeed;

            if (keys.IsKeyDown(Keys.Right))
                leftRightRot += turningSpeed;
            if (keys.IsKeyDown(Keys.Left))
                leftRightRot -= turningSpeed;

            float upDownRot = 0;
            if (keys.IsKeyDown(Keys.Down))
                upDownRot += turningSpeed;
            if (keys.IsKeyDown(Keys.Up))
                upDownRot -= turningSpeed;

            Quaternion additionalRot = Quaternion.CreateFromAxisAngle(new Vector3(0, 0, -1), leftRightRot) * Quaternion.CreateFromAxisAngle(new Vector3(1, 0, 0), upDownRot);
            Quaternion localXwingRot = localXwing.Rotation;

            localXwingRot *= additionalRot;
            localXwing.Rotation = localXwingRot;

            if (keys.IsKeyDown(Keys.Space))
            {
                double currentTime = gameTime.TotalGameTime.TotalMilliseconds;
                if (currentTime - localXwing.LastBulletTime > 800)
                {
                    localXwing.LastBulletTime = currentTime;
                    Bullet newBullet = new Bullet();
                    newBullet.bulletPosition = localXwing.Position;
                    newBullet.bulletRotation = localXwing.Rotation;
                    newBullet.bulletOwner = localXwing.PlayerID;

                    //if server exist
                    if (DistributionSession.Server != null)
                    {
                        DistributionSession.ServerCreate(newBullet);
                    }
                    else
                    {
                        DistributionSession.DistributeObject(newBullet);
                    }


                    float speed = (float)random_number.Next(5) / 100f;
                    //float speed = localXwing.MoveSpeed;// (float)random_number.Next(50) / 100f;
                    speed += .08f;

                    //todo remove?
                    view_frustum = new BoundingFrustum(viewMatrix * projectionMatrix);
                    frustum_corners = view_frustum.GetCorners();

                    target_direction = Vector3.Normalize(frustum_corners[5] - frustum_corners[3]);
                    //end todo

                    Vector3 targetDir = MoveForward(localXwing.Position, localXwing.Rotation, 1000.0f);
                    Vector3 directionVector = Vector3.Normalize(targetDir - localXwing.Position);

                    //Laserbolts.setup_and_fire(frustum_corners[3], target_direction, randcolors.gimmie(), speed, true);
                    Random randomLaserBoltPos = new Random();
                    int randPos = randomLaserBoltPos.Next(-5, 5);
                    Vector3 addSomeMovement = MoveForward(localXwing.Position, localXwing.Rotation, localXwing.MoveSpeed * 3);

                    Vector3 turrer1Pos = Vector3.Transform(localXwing.Position + new Vector3(-0.07f, 0, 0), Matrix.CreateFromQuaternion(new Quaternion(localXwing.Rotation.X, 0f, 0f, localXwing.Rotation.W)));

                    Matrix xWingMatrix = Matrix.CreateFromQuaternion(localXwing.Rotation);

                    //Vector3 upperLeftTurret = Matrix.CreateFromQuaternion(Rotation) * Matrix.CreateTranslation(Position)
                    BoundingBox bBox = GetBoundingBoxFromModel(xwingModel); //BoundingBox.CreateFromSphere(new BoundingSphere(localXwing.Position, 0.07f));                   
                    Vector3[] corners = bBox.GetCorners();

                    // GetBoundingBoxFromModel(xwingModel);

                    //-0.07f
                    //Vector3 upperLeftTurret = localXwing.Position + new Vector3( xWingMatrix.Left.X * 0.07f,xWingMatrix.Up.Y*0.07f, 0);

                    Matrix worldMatrix = Matrix.CreateScale(0.0005f, 0.0005f, 0.0005f) * Matrix.CreateRotationY(MathHelper.Pi) * Matrix.CreateFromQuaternion(localXwing.Rotation) * Matrix.CreateTranslation(localXwing.Position + new Vector3(-0.07f, 0, 0));

                    //  Laserbolts.setup_and_fire(new Vector3(corners[0].X, corners[0].Y, localXwing.Position.Z), directionVector, randcolors.gimmie(), speed, false);//, Matrix.CreateTranslation(localXwing.Position));
                    Laserbolts.setup_and_fire(localXwing.Position, targetDir, randcolors.gimmie(), speed, false);


                }
            }
            for (int i = 0; i < 200; i++) Laserbolts.bolt[i].update();
            localXwing.MoveSpeed = localXwing.NormalSpeed;
            if (keys.IsKeyDown(Keys.Z))
            {
                localXwing.MoveSpeed = localXwing.NormalSpeed / 4;
            }

            if (keys.IsKeyDown(Keys.X))
            {
                localXwing.MoveSpeed = localXwing.NormalSpeed * 4;
            }
        }

        MouseState mouseState;
        MouseState oldMouseState;
        float upDownRot;

        void ReadRebelInputs(GameTime gameTime)
        {
            float time = (float)gameTime.ElapsedGameTime.TotalMilliseconds;
            KeyboardState keys = Keyboard.GetState();       
       
            float leftRightRot = 0;
            upDownRot = 0;
            localRebel.ForwardSpeed = 0;
            localRebel.StrafeSpeed = 0;

            float turningSpeed = (float)gameTime.ElapsedGameTime.TotalMilliseconds / 1000.0f;
            turningSpeed = 0.3f * gameSpeed;
           // float timeDifference = (float)gameTime.ElapsedGameTime.TotalMilliseconds / 1000.0f; // 
            float amount = 0.1f;

            MouseState currentMouseState = Mouse.GetState();
            if (currentMouseState != oldMouseState)
            {
                float xDifference = currentMouseState.X - oldMouseState.X;
                float yDifference = currentMouseState.Y - oldMouseState.Y;
                leftRightRot -= turningSpeed * xDifference * amount;
                upDownRot -= turningSpeed * yDifference * amount;
                if (xDifference > 0)
                {
                   rebelCameraArc += turningSpeed * time * 0.1f;
                }
                if (xDifference < 0)
                {
                  rebelCameraArc -= turningSpeed * time * 0.1f;
                }

                // Limit the arc movement.
                if (rebelCameraArc > 90.0f)
                    rebelCameraArc = 90.0f;
                else if (rebelCameraArc < -90.0f)
                    rebelCameraArc = -90.0f;

                //rebelCameraArc += currentGamePadState.ThumbSticks.Right.Y * time * 0.25f;
              //  rebelCameraRotation = leftRightRot;
                Mouse.SetPosition(device.Viewport.Width / 2, device.Viewport.Height / 2);
                //UpdateViewMatrix();
            }

            ////rotate
            //if (mousex < oldMouseX)
            //    upDownRot += turningSpeed;
            //if (mousex > oldMouseX)
            //    upDownRot -= turningSpeed;                     
            //if (keys.IsKeyDown(Keys.Left))
            //    leftRightRot += turningSpeed;
            //if (keys.IsKeyDown(Keys.Right))
            //    leftRightRot -= turningSpeed;

            //if (keys.IsKeyDown(Keys.Right))
            //    localRebel.StrafeSpeed = -localRebel.NormalSpeed;
            //if (keys.IsKeyDown(Keys.Left))
            //    localRebel.StrafeSpeed = localRebel.NormalSpeed;
            //if (keys.IsKeyDown(Keys.Up))
            //    rebelCameraArc -= time * 0.1f;
            //if (keys.IsKeyDown(Keys.Down))
            //    rebelCameraArc += time * 0.1f;


            //walking
            if (keys.IsKeyDown(Keys.Right))
                localRebel.StrafeSpeed = -localRebel.NormalSpeed;
            if (keys.IsKeyDown(Keys.Left))
                localRebel.StrafeSpeed = localRebel.NormalSpeed;
            if (keys.IsKeyDown(Keys.Up))
                localRebel.ForwardSpeed = localRebel.NormalSpeed;
            if (keys.IsKeyDown(Keys.Down))
                localRebel.ForwardSpeed = -localRebel.NormalSpeed;


                
            Quaternion additionalRot = Quaternion.CreateFromAxisAngle(new Vector3(0, 1, 0), leftRightRot) * Quaternion.CreateFromAxisAngle(new Vector3(1, 0, 0), upDownRot);
            Quaternion localRebelRot = localRebel.Rotation;

            localRebelRot *= additionalRot;
            localRebel.Rotation = localRebelRot;

            if (ButtonState.Pressed == mouseState.LeftButton)
            {
                double currentTime = gameTime.TotalGameTime.TotalMilliseconds;
                if (currentTime - localRebel.LastBulletTime > 800)
                {
                    localRebel.LastBulletTime = currentTime;
                    Bullet newBullet = new Bullet();
                    newBullet.bulletPosition = localRebel.Position;
                    newBullet.bulletRotation = localRebel.Rotation;
                    newBullet.bulletOwner = localRebel.PlayerID;

                    //if server exist
                    if (DistributionSession.Server != null)
                    {
                        DistributionSession.ServerCreate(newBullet);
                    }
                    else
                    {
                        DistributionSession.DistributeObject(newBullet);
                    }


                    float speed = (float)random_number.Next(5) / 100f;
                    //float speed = localXwing.MoveSpeed;// (float)random_number.Next(50) / 100f;
                    speed += .08f;

                    Vector3 targetDir = MoveForward(localRebel.Position, localRebel.Rotation, 1000.0f);
                    //Vector3 directionVector = Vector3.Normalize(targetDir - localRebel.Position);
                
                    Laserbolts.setup_and_fire(localRebel.Position + new Vector3(0,0.5f,0), targetDir, randcolors.gimmie(), speed, false);
                }
            }

          // oldMouseState = mouseState;

            for (int i = 0; i < 200; i++) Laserbolts.bolt[i].update();                
        }


        public BoundingBox GetBoundingBoxFromModel(Model myModel)
        {
            BoundingBox modelBox = new BoundingBox();


            //foreach (ModelMesh mesh in model.Meshes)
            //{
            //    VertexPositionNormalTexture[] vertices =
            //      new VertexPositionNormalTexture[mesh.VertexBuffer.SizeInBytes / VertexPositionNormalTexture.SizeInBytes];

            //    mesh.VertexBuffer.GetData<VertexPositionNormalTexture>(vertices);

            //    Vector3[] vertexs = new Vector3[vertices.Length];

            //    for (int index = 0; index < vertexs.Length; index++)
            //    {
            //        vertexs[index] = vertices[index].Position;
            //    }

            //    boundingBox = BoundingBox.CreateMerged(boundingBox,
            //      BoundingBox.CreateFromPoints(vertexs));
            //}

            //BoundingBox modelBox;
            bool firstBox = true; foreach (ModelMesh mesh in myModel.Meshes) { BoundingBox meshBox = BoundingBox.CreateFromSphere(mesh.BoundingSphere); if (firstBox)      modelBox = meshBox; else      modelBox = BoundingBox.CreateMerged(modelBox, meshBox); }

            return modelBox;
        }


        #endregion


        #region Draw


        /// <summary>
        /// This is called when the game should draw itself.
        /// </summary>
        protected override void Draw(GameTime gameTime)
        {
            //      GraphicsDevice.Clear(Color.CornflowerBlue);
            //device.Clear(ClearOptions.Target | ClearOptions.DepthBuffer, Color.DarkSlateBlue, 1.0f, 0);           
            device.Clear(Color.DarkRed);

            //keep
            Blend currentBlend = graphics.GraphicsDevice.RenderState.SourceBlend;
            bool currentAlphaBlendEnable = graphics.GraphicsDevice.RenderState.AlphaBlendEnable;
            Blend currentDestBlend = graphics.GraphicsDevice.RenderState.DestinationBlend;

            graphics.GraphicsDevice.RenderState.AlphaBlendEnable = true;
            graphics.GraphicsDevice.RenderState.SourceBlend = Blend.SourceAlpha;
            graphics.GraphicsDevice.RenderState.DestinationBlend = Blend.InverseSourceAlpha;


            Laserbolts.draw(viewMatrix, projectionMatrix, graphics.GraphicsDevice, your_effect);

            graphics.GraphicsDevice.RenderState.AlphaBlendEnable = currentAlphaBlendEnable;
            graphics.GraphicsDevice.RenderState.SourceBlend = currentBlend;
            graphics.GraphicsDevice.RenderState.DestinationBlend = currentDestBlend;

            //keep

            if (DistributionSession.Client == null && DistributionSession.Server == null && multiPlayerGame)
            {
                // If we are not in a network session, draw the
                // menu screen that will let us create or join one.                          
            }
            else
            {
                // If we are in a network session, draw it.
                DrawGame();
            }

            base.Draw(gameTime);
        }



        #endregion


    }
}

